package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.UserInfo;
import com.wzcl.app.dao.repository.UserInfoRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.dto.UserInfoDto;
import com.wzcl.app.service.UserInfoService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Log4j2
@Service
public class UserInfoServiceImpl implements UserInfoService {

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Override
    public UserInfo addUserInfo(UserInfoDto userInfoDto) {
        UserInfo userinfo = new UserInfo();
        BeanUtils.copyProperties(userInfoDto,userinfo,"id");
        return userInfoRepository.save(userinfo);
    }

    @Override
    public UserInfo delUserInfoById(Integer id) {
        UserInfo userInfo = getUserInfoById(id);
        if(userInfo == null){
            throw new BusinessException(CodeMsg.USER_INFO_NOT_EXIST);
        }
        log.info("UserInfo:{} Physical deletion", JSON.toJSONString(userInfo));
        userInfoRepository.delete(userInfo);
        return userInfo;
    }

    @Override
    public UserInfo updateUserInfo(UserInfoDto userInfoDto) {
        if(userInfoDto.getId() == null){
            return addUserInfo(userInfoDto);
        }else {
            UserInfo userInfo = getUserInfoById(userInfoDto.getId());
            if (userInfo == null) {
                throw new BusinessException(CodeMsg.USER_INFO_NOT_EXIST);
            }
            BeanUtils.copyProperties(userInfoDto, userInfo, "id");
            return userInfoRepository.save(userInfo);
        }
    }

    @Override
    public UserInfo getUserInfoById(Integer id) {
        Optional<UserInfo> optional = userInfoRepository.findById(id);
        return optional.orElse(null);
    }

    @Override
    public List<UserInfo> getUseList(UserInfoDto userInfoDto) {
        return userInfoRepository.findAll(getSpecification(userInfoDto),userInfoDto.getSort());
    }

    private Specification<UserInfo> getSpecification(UserInfoDto userInfoDto){
        return new Specification<UserInfo>() {
            @Override
            public Predicate toPredicate(Root<UserInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }
}
